#pragma once
#include "ManagedCryptBlob.h"
using namespace System;

namespace Safe
{
	/// <summary>
	/// Parses an RFC3161 timestamp server response
	/// </summary>
	public ref class TimestampResponse
	{
	private:
		DateTime^ m_timestampTime;

		/// <summary>
		/// Decodes the ASN-encoded timestamp token content object.  This function can
		/// throw a TimestampException if the hash in the timestamp does not match the hash passed
		/// into the function.  This function can throw an AsnException if there are errors decoding
		/// the timestamp response.  This function can throw a ChainBuildException if the timestamp
		/// authority's certificate is invalid or untrusted, or if it does not contain appropriate
		/// extended key usage.
		/// </summary>
		/// <param name='pContent'>The ASN encoded timestamp token extracted from the response</param>
		/// <param name='dContent'>The length of the pContent buffer</param>
		/// <param name='hashOid'>The algorithm identifier of the hash algorithm used to create
		/// the timestamp request hash</param>
		/// <param name='hash'>The hash value to compare against the hash in the timestamp response</param>
		void DecodeTstContent(BYTE * pContent, DWORD cContent, const char *hashOid, CRYPT_DER_BLOB *hash);

		/// <summary>
		/// Decodes the ASN-encoded timestamp response.
		/// This function can throw an AsnException if there are errors decoding
		/// the timestamp response.  This function can throw a ChainBuildException if the timestamp
		/// authority's certificate is invalid or untrusted, or if it does not contain appropriate
		/// extended key usage.
		/// </summary>
		/// <param name='pData'>The ASN encoded timestamp response</param>
		/// <param name='cData'>The length of the pData buffer</param>
		/// <param name='hashOid'>The algorithm identifier of the hash algorithm used to create
		/// the timestamp request hash</param>
		/// <param name='hash'>The hash value to compare against the hash in the timestamp response</param>
		void DecodeResponse(BYTE * pData, DWORD cData, const char *hashOid, CRYPT_DER_BLOB *hash);

	public:
		/// <summary>
		/// Creates a new TimestampResponse
		/// This function can throw an AsnException if there are errors decoding
		/// the timestamp response.  This function can throw a ChainBuildException if the timestamp
		/// authority's certificate is invalid or untrusted, or if it does not contain appropriate
		/// extended key usage.
		/// </summary>
		/// <param name='pData'>The binary HTTP response read from the timestamp responder</param>
		/// <param name='cData'>The length of the pData  buffer</param>
		/// <param name='hashOid'>The algorithm identifier of the hash used to create the timestamp
		/// request</param>
		/// <param name='hash'>The hash to compare against the hash in the timestamp response</param>
		TimestampResponse(BYTE * pData, DWORD cData, const char *hashOid, CRYPT_DER_BLOB *hash);

		/// <summary>
		/// Creates a new TimestampResponse
		/// This function can throw an AsnException if there are errors decoding
		/// the timestamp response.  This function can throw a ChainBuildException if the timestamp
		/// authority's certificate is invalid or untrusted, or if it does not contain appropriate
		/// extended key usage.
		/// </summary>
		/// <param name='data'>The binary HTTP response read from the timestamp responder</param>
		/// <param name='hashOid'>The algorithm identifier of the hash used to create the timestamp
		/// request</param>
		/// <param name='hash'>The hash to compare against the hash in the timestamp response</param>
		TimestampResponse(array<unsigned char>^ data, String^ hashOid, ManagedCryptBlob^ hash);

		/// <summary>
		/// Destructor
		/// </summary>
		~TimestampResponse(void);

		/// <summary>
		/// Gets the time contained in the signed timestamp.  This property is read-only.
		/// </summary>
		property DateTime^ TimestampTime { 
			DateTime^ get() { 
				return m_timestampTime;
			}
		}
	};
}
